package repository

import (
	"fitness/go-admin/internal/model"

	"gorm.io/gorm"
)

// MenuRepository 菜单仓库接口
type MenuRepository interface {
	Create(menu *model.Menu) error
	GetByID(id uint) (*model.Menu, error)
	List() ([]model.Menu, error)
	GetMenuTree() ([]model.MenuTree, error)
	Update(menu *model.Menu) error
	Delete(id uint) error
	UpdateStatus(id uint, status int) error
}

// menuRepository 菜单仓库实现
type menuRepository struct {
	db *gorm.DB
}

// NewMenuRepository 创建菜单仓库实例
func NewMenuRepository(db *gorm.DB) MenuRepository {
	return &menuRepository{db: db}
}

// Create 创建菜单
func (r *menuRepository) Create(menu *model.Menu) error {
	return r.db.Create(menu).Error
}

// GetByID 根据ID获取菜单
func (r *menuRepository) GetByID(id uint) (*model.Menu, error) {
	var menu model.Menu
	err := r.db.First(&menu, id).Error
	return &menu, err
}

// List 获取菜单列表
func (r *menuRepository) List() ([]model.Menu, error) {
	var menus []model.Menu
	err := r.db.Order("parent_id ASC, order ASC").Find(&menus).Error
	return menus, err
}

// GetMenuTree 获取菜单树形结构
func (r *menuRepository) GetMenuTree() ([]model.MenuTree, error) {
	var menus []model.Menu
	if err := r.db.Order("parent_id ASC, order ASC").Find(&menus).Error; err != nil {
		return nil, err
	}

	// 构建树形结构
	menuMap := make(map[uint]*model.MenuTree)
	for _, menu := range menus {
		menuCopy := menu // 创建副本避免循环引用
		menuMap[menuCopy.ID] = &model.MenuTree{Menu: menuCopy}
	}

	var tree []model.MenuTree
	for _, menu := range menus {
		if menu.ParentID == 0 {
			// 根节点
			node := menuMap[menu.ID]
			buildMenuTree(node, menuMap)
			tree = append(tree, *node)
		}
	}

	return tree, nil
}

// buildMenuTree 构建菜单树
func buildMenuTree(node *model.MenuTree, menuMap map[uint]*model.MenuTree) {
	for _, child := range menuMap {
		if child.ParentID == node.ID {
			buildMenuTree(child, menuMap)
			node.Children = append(node.Children, *child)
		}
	}
}

// Update 更新菜单
func (r *menuRepository) Update(menu *model.Menu) error {
	return r.db.Save(menu).Error
}

// Delete 删除菜单
func (r *menuRepository) Delete(id uint) error {
	return r.db.Delete(&model.Menu{}, id).Error
}

// UpdateStatus 更新菜单状态
func (r *menuRepository) UpdateStatus(id uint, status int) error {
	return r.db.Model(&model.Menu{}).Where("id = ?", id).Update("status", status).Error
}
